//------------------------------------------------------------------------------
//	file
//		lpc1125-read-info.c
//
//	brief
//		Read ID information from an LPC1125
//
//	description
//
//	$Id: lpc1125-read-info.c 321 2015-01-21 23:02:50Z ac.verbeck@gmail.com $
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
//	The MIT License (MIT)
//
//	Copyright (c) 2015 A.C. Verbeck
//
//	Permission is hereby granted, free of charge, to any person obtaining a copy
//	of this software and associated documentation files (the "Software"), to deal
//	in the Software without restriction, including without limitation the rights
//	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//	copies of the Software, and to permit persons to whom the Software is
//	furnished to do so, subject to the following conditions:
//
//	The above copyright notice and this permission notice shall be included in
//	all copies or substantial portions of the Software.

//	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//	THE SOFTWARE.
//------------------------------------------------------------------------------
#include <windows.h>
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>

static DWORD s_read(HANDLE hSerial, uint8_t* buff, int buff_sz);
static DWORD s_write(HANDLE hSerial, uint8_t* buff, int buff_sz);

#define	BUFF_CT		128
static uint8_t buff_i[BUFF_CT];
static uint8_t buff_o[BUFF_CT];

int main()
{
	LPCSTR portname = "COM8";
	DWORD  accessdirection = GENERIC_READ | GENERIC_WRITE;
	HANDLE hSerial = NULL;
	DCB dcbSerialParams = {0};
	COMMTIMEOUTS timeouts= {0};

	uint32_t chip_id;

//
//	Open the serial port
//
	hSerial = CreateFile(portname, accessdirection, 0, 0, OPEN_EXISTING, 0, 0);
	if (hSerial == INVALID_HANDLE_VALUE) {
		printf("Could not open comm port\r\n");
		printf("Error code: %d\r\n", (int)GetLastError());
	}

//
//	Set serial parameters
//
	dcbSerialParams.DCBlength=sizeof(dcbSerialParams);
	if (GetCommState(hSerial, &dcbSerialParams) == 0) {
		printf("Could not get comport state\r\n");
		printf("Error code: %d\r\n", (int)GetLastError());
		exit(1);
	}

	dcbSerialParams.BaudRate=115200;
	dcbSerialParams.ByteSize=8;
	dcbSerialParams.StopBits=ONESTOPBIT;
	dcbSerialParams.Parity=NOPARITY;

	if (SetCommState(hSerial, &dcbSerialParams) == 0 ) {
		printf("Could not get comport state\r\n");
		printf("Error code: %d\r\n", (int)GetLastError());
		exit(1);
	}

//
//	Set timeouts
//
	timeouts.ReadIntervalTimeout=50;
	timeouts.ReadTotalTimeoutConstant=50;
	timeouts.ReadTotalTimeoutMultiplier=10;
	timeouts.WriteTotalTimeoutConstant=50;
	timeouts.WriteTotalTimeoutMultiplier=10;

	if(SetCommTimeouts(hSerial, &timeouts) == 0) {
		printf("Could not set comport time-outs\r\n");
		printf("Error code: %d\r\n", (int)GetLastError());
		exit(1);
	}

//
//	Synchronize communication with the LPC1125
//
//
	memset(buff_i, 0, BUFF_CT);
	memset(buff_o, 0, BUFF_CT);
	sprintf((char*)buff_o,"?");
	s_write(hSerial, buff_o, 1);
	s_read(hSerial, buff_i, 64);
//	printf("%s",buff_i);

	memset(buff_i, 0, BUFF_CT);
	memset(buff_o, 0, BUFF_CT);
	sprintf((char*)buff_o,"Synchronized\r\n");
	s_write(hSerial, buff_o, 14);
	s_read(hSerial, buff_i, 64);
//	printf("%s",buff_i);

	memset(buff_i, 0, BUFF_CT);
	memset(buff_o, 0, BUFF_CT);
	sprintf((char*)buff_o,"\r\n");
	s_write(hSerial, buff_o, 2);
	s_read(hSerial, buff_i, 64);
//	printf("%s",buff_i);


//
//	Send first command to the LPC1125:
//	J - read part ID
//
	memset(buff_i, 0, BUFF_CT);
	memset(buff_o, 0, BUFF_CT);
	sprintf((char*)buff_o,"J\r\n");
	s_write(hSerial, buff_o, 3);
	s_read(hSerial, buff_i, 32);
	sscanf((char*)(buff_i+6), "%d", &chip_id);
	printf("Chip ID: 0x%x\r\n",chip_id);

//
//	Send second command to the LPC1125:
//	K - read boot code version
//
	memset(buff_i, 0, BUFF_CT);
	memset(buff_o, 0, BUFF_CT);
	sprintf((char*)buff_o,"K\r\n");
	s_write(hSerial, buff_o, 3);
	s_read(hSerial, buff_i, 32);
	printf("Boot Code Version: %c.%c\r\n",*(buff_i+6), *(buff_i+9));

	CloseHandle(hSerial);
}


static DWORD s_read(HANDLE hSerial, uint8_t* buff, int buff_sz)
{
	DWORD dw_read = 0;

	if (ReadFile(hSerial, buff, buff_sz, &dw_read, NULL) == 0) {
		printf("ReadFile: failed\r\n");
		printf("Error code: %d\r\n", (int)GetLastError());
		exit(1);
	}

	return dw_read;
}

static DWORD s_write(HANDLE hSerial, uint8_t* buff, int buff_sz)
{
	DWORD dw_write = 0;

	if (WriteFile(hSerial, buff, buff_sz, &dw_write, NULL) == 0) {
		printf("WriteFile: failed\r\n");
		printf("Error code: %d\r\n", (int)GetLastError());
		exit(1);
	}

	return dw_write;
}
